package com.umfwechat.core.exception.handler;

import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.spi.ThrowableInformation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import com.umfwechat.util.PropertyUtil;
import com.umfwechat.util.email.MailSendLoop;
import com.umfwechat.util.email.SendEmailThread;

/**
 * 全局异常处理器
 * 
 * @author hopeone
 *
 */
public class GlobalExceptionResolver extends SimpleMappingExceptionResolver {
	private static Logger logger = LoggerFactory.getLogger(GlobalExceptionResolver.class);
	@Override
	protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
		exceptionHandler(request, response, handler, ex);
		HandlerMethod handlerMethod = (HandlerMethod) handler;
		ResponseBody body = handlerMethod.getMethodAnnotation(ResponseBody.class);
		if (body == null) {
			return super.doResolveException(request, response, handler, ex);
		}
		ModelAndView mv = new ModelAndView();
		// 设置状态码
		response.setStatus(HttpStatus.OK.value());
		// 设置ContentType
		response.setContentType(MediaType.APPLICATION_JSON_VALUE);
		// 避免乱码
		response.setCharacterEncoding("UTF-8");
		response.setHeader("Cache-Control", "no-cache, must-revalidate");
		try {
			response.getWriter().write("{success:false,msg:" + ex.getMessage() + "}");
		} catch (IOException e) {
			logger.error("输入输出流IO异常",e);
		}

		return mv;
	}


	/**
	 * 异常发送邮件出来
	 * @param ex
	 */
	private void exceptionHandler(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex){
		String mailTo = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties", "plat.exception.email.to", "");
//		String mailTo = PropertiesTool.getValue("plat.exception.email.to");
		String busiParams = "";//业务参数
		
		String reqParams_method = request.getMethod();
		String reqParams_getContextPath = request.getContextPath();
		String reqParams_getProtocol = request.getProtocol();
		String reqParams_getQueryString = request.getQueryString();
		String reqParams_getRequestedSessionId = request.getRequestedSessionId();
		String reqParams_getRequestURI = request.getRequestURI();
		String reqParams_getServerName = request.getServerName();
		String reqParams_getServletPath = request.getServletPath();
		String reqParams_getParameterMap = request.getParameterMap().toString();
		
		
		
		StringBuilder mailContent = new StringBuilder();
		
		String strLine = "\r";
		mailContent.append("服务器:"+SERVER_IP).append(strLine);
		mailContent.append("reqParams_method:"+reqParams_method).append(strLine);
		mailContent.append("reqParams_getContextPath:"+reqParams_getContextPath).append(strLine);
		mailContent.append("reqParams_getProtocol:"+reqParams_getProtocol).append(strLine);
		mailContent.append("reqParams_getQueryString:"+reqParams_getQueryString).append(strLine);
		mailContent.append("reqParams_getRequestedSessionId:"+reqParams_getRequestedSessionId).append(strLine);
		mailContent.append("reqParams_getRequestURI:"+reqParams_getRequestURI).append(strLine);
		mailContent.append("reqParams_getServerName:"+reqParams_getServerName).append(strLine);
		mailContent.append("reqParams_getServletPath:"+reqParams_getServletPath).append(strLine);
		mailContent.append("reqParams_getParameterMap:"+reqParams_getParameterMap).append(strLine);
		mailContent.append("exception message:"+getExceptionStr(ex)).append(strLine);
		
		MailSendLoop.sendEmail(new SendEmailThread("WeChatAppException",mailContent,mailTo));
	}
	
	public String getExceptionStr(Exception re){
		ThrowableInformation throwInfo = new ThrowableInformation(re);
		StringBuilder sb = new StringBuilder();
		for (String stackTrace : throwInfo.getThrowableStrRep())
		{
			sb.append(stackTrace.toString() + "\n   ");
		}
		return sb.toString();
	}
	
	private static String SERVER_IP = getMyIp();
	@SuppressWarnings("rawtypes")
	private static String getMyIp() {
		String localip = null;
		String netip = null;
		try {
			Enumeration netInterfaces = NetworkInterface.getNetworkInterfaces();
			InetAddress ip = null;
			boolean finded = false;
			while (netInterfaces.hasMoreElements() && !finded) {
				NetworkInterface ni = (NetworkInterface) netInterfaces
						.nextElement();
				Enumeration address = ni.getInetAddresses();
				while (address.hasMoreElements()) {
					ip = (InetAddress) address.nextElement();
					if (!ip.isSiteLocalAddress() && !ip.isLoopbackAddress()
							&& ip.getHostAddress().indexOf(":") == -1) {
						netip = ip.getHostAddress();
						finded = true;
						break;
					} else if (ip.isSiteLocalAddress()
							&& !ip.isLoopbackAddress()
							&& ip.getHostAddress().indexOf(":") == -1) {
						localip = ip.getHostAddress();
					}
				}
			}
		} catch (SocketException e) {
			logger.error("SocketException",e);
		}
		
       
		if (netip != null && !"".equals(netip)) {
			return netip;
		} else {
			return localip;
		}
	}

}
